package fiuba.algo3.persistencia;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.io.xml.DomDriver;

import fiuba.algo3.modelo.*;
import fiuba.algo3.modelo.vehiculo.*;
import fiuba.algo3.modelo.factorVial.*;
import fiuba.algo3.modelo.mapa.*;
import fiuba.algo3.usuario.Usuario;

// Esta clase se la mantuvo publica para permitir testeo a fondo. En la practica, se usan
// siempre las clases Guardador y Restaurador, que internamente usan a esta.
public class TraductorXml {

	private String pasarAXml(Object objeto){
		XStream xstream = new XStream(new DomDriver());
		setear(xstream);
		String xml = xstream.toXML(objeto);
		return xml;
	}
	
	public void guardarComoXml(Object objeto, String path) throws IOException{
        BufferedWriter out = new BufferedWriter(new FileWriter(path));
        out.write( pasarAXml(objeto));
        out.close();
	}

	
	public Object recuperar(String path) throws IOException{
		XStream xstream = new XStream(new DomDriver());
		setear(xstream);
		Object objeto = xstream.fromXML(new File(path));
		return objeto;
	}
	
	private void setear(XStream xstream){
		xstream.alias("Vehiculo", Vehiculo.class);
		xstream.alias("Auto", Auto.class);
		xstream.alias("Moto", Moto.class);
		xstream.alias("TodoTerreno", TodoTerreno.class);
		
		xstream.alias("Sorpresa", Sorpresa.class);
		xstream.alias("SorpresaCambio", SorpresaCambio.class);
		xstream.alias("SorpresaFavorable", SorpresaFavorable.class);
		xstream.alias("SorpresaDesfavorable", SorpresaDesfavorable.class);
		
		xstream.alias("Obstaculo", Obstaculo.class);
		xstream.alias("Pozo", Pozo.class);
		xstream.alias("Piquete", Piquete.class);
		xstream.alias("ControlPolicial", ControlPolicial.class);
		
		xstream.alias("Partida", Partida.class);
		xstream.alias("Mapa", Mapa.class);
		xstream.alias("Cruce", Cruce.class);
		xstream.alias("Calle", Calle.class);
		xstream.alias("Posicion", Posicion.class);
		xstream.alias("Direccion", Direccion.class);
		
		xstream.alias("Usuario", Usuario.class);
		
		xstream.registerConverter(new PosicionConverter());
		xstream.registerConverter(new UsuarioConverter());
	}
	
	private class PosicionConverter implements SingleValueConverter{

        public String toString(Object object) {
        	Posicion posicion = (Posicion) object;
        	String X = new Integer(posicion.getX()).toString();
        	String Y = new Integer(posicion.getY()).toString();
            String string; 
            string = "( " + X + " ; " + Y + " )";
        	return string;
        }

        public Object fromString(String posicion) {
        	String[] XY = posicion.split(" ");
        	//esto depende de como se arma el string en el metodo toString()
        	int x = Integer.parseInt(XY[1]);
        	int y = Integer.parseInt(XY[3]);
        	return new Posicion(x,y);
        }

        @SuppressWarnings("rawtypes")
		public boolean canConvert(Class type) {
        	return type.equals(Posicion.class);
        }

	}
	
	
	private class UsuarioConverter implements SingleValueConverter{

        public String toString(Object object) {
        	Usuario usuario = (Usuario) object;
            String string; 
            string = "nombre= _" + usuario.getNombre() + 
            		"_ \tpuntajeMaximo= _" + new Integer(usuario.getPuntajeMaximo()).toString()+"_";
        	return string;
        }

        public Object fromString(String stringAtributos) {
        	//esto depende de como se arma el string en el metodo toString()
        	String[] strings = stringAtributos.split("_");
        	String nombre = strings[1];
        	int puntajeMaximo = Integer.parseInt(strings[3]);
        	Usuario usuario = new Usuario(nombre);
        	usuario.recalcularPuntajeMaximo(puntajeMaximo);
        	return usuario;
        }

        @SuppressWarnings("rawtypes")
		public boolean canConvert(Class type) {
        	return type.equals(Usuario.class);
        }

	}
}
